import 'dart:math';

import 'package:flutter/material.dart';

///**
///* @author hrongyong
///* @date   2/21/21
///* @email hrongyong@gmail.com
///* Description: 
///*/
class WaveLoadingPainter extends CustomPainter {
  //如果外部没有指定颜色值，则使用此默认颜色值
  static final Color defaultColor = Colors.lightBlue;

  //画笔对象
  var _paint = Paint();

  //圆形路径
  Path _circlePath = Path();

  //波浪路径
  Path _wavePath = Path();

  //要显示的文本
  final String text;

  //字体大小
  final double fontSize;

  final Color backgroundColor;

  final Color foregroundColor;

  final Color waveColor;

  //波浪线比例
  final double proportion;

  WaveLoadingPainter(
      {this.text,
        this.fontSize,
        this.backgroundColor,
        this.foregroundColor,
        this.waveColor,
        this.proportion}) {
    _paint
      ..isAntiAlias = true
      ..style = PaintingStyle.fill
      ..strokeWidth = 3
      ..color = waveColor ?? defaultColor;
  }

  @override
  void paint(Canvas canvas, Size size) {
    double side = min(size.width, size.height);
    double radius = side / 2.0;

    ///边线
    canvas.drawCircle(
        Offset(size.width / 2, size.height / 2),
        side / 2,
        Paint()
          ..color = this.backgroundColor
          ..style = PaintingStyle.stroke);
    if (proportion >= 1.0) {
      canvas.drawCircle(
          Offset(size.width / 2, size.height / 2),
          (side * 0.9) / 2,
          Paint()
            ..color = this.backgroundColor
            ..style = PaintingStyle.fill);
      _drawText(
          canvas: canvas,
          side: side,
          colors: foregroundColor,
          widgetSize: size);

      return;
    }

    _drawText(
        canvas: canvas, side: side, colors: backgroundColor, widgetSize: size);

    _circlePath.reset();
    _circlePath.addArc(
        Rect.fromCenter(
            center: Offset(size.width / 2, size.height / 2),
            width: side * 0.9,
            height: side * 0.9),
        0,
        2 * pi);

    //画波浪
    double waveWidth = side * 0.25;
    double waveHeight = side / 10;
    _wavePath.reset();
    _wavePath.moveTo(-waveWidth, size.height * (1 - this.proportion));
    for (double i = -waveWidth; i < side; i += waveWidth) {
      _wavePath.relativeQuadraticBezierTo(
          waveWidth / 4, -waveHeight, waveWidth / 2, 0);
      _wavePath.relativeQuadraticBezierTo(
          waveWidth / 4, waveHeight, waveWidth / 2, 0);
    }
    _wavePath.relativeLineTo(0, radius);
    // _wavePath.lineTo(-waveWidth, side);
    _wavePath.lineTo(-waveWidth, side * 3); //要加多1倍，不然很难覆盖全部
    _wavePath.close();

    var combine = Path.combine(PathOperation.intersect, _circlePath, _wavePath);
    canvas.drawPath(combine, _paint);

    canvas.clipPath(combine);
    _drawText(
        canvas: canvas, side: side, colors: foregroundColor, widgetSize: size);
  }

  void _drawText({Canvas canvas, double side, Color colors, Size widgetSize}) {
    TextPainter textPainter = TextPainter(
        text: TextSpan(
            text: this.text,
            style: TextStyle(fontSize: this.fontSize, color: colors)),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr);
    textPainter.layout(); // 进行布局
    Size size = textPainter.size; // 尺寸必须在布局后获取
    textPainter.paint(
        canvas,
        Offset((widgetSize.width - size.width) / 2,
            (widgetSize.height - size.height) / 2));
  }

  @override
  bool shouldRepaint(WaveLoadingPainter oldDelegate) => false;
}
